
#include "../luaVector.h"
#include <complex>
#ifndef __cplusplus
#include "stdlib.h"
#endif
#include "string.h"

#include "tolua++.h"

namespace std{

	template<>
	std::vector<double> add<double>(std::vector<double>* a, double b)
	{
		std::vector<double> res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] + b;
		return res;
	}
	template<>
	std::vector< std::complex<double> > add< std::complex<double> >(std::vector< std::complex<double> >* a, double b)
	{
		std::vector<  std::complex<double> > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] + b;
		return res;
	}

	template<>
	std::vector< std::vector<double> > add< std::vector<double> >(std::vector< std::vector<double> >* a, double b)
	{
		std::vector<   std::vector<double>  > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
		{
			res[ii].resize( (*a)[ii].size() );
			for( int jj=0; jj < res[ii].size(); jj++)
			{
				res[ii][jj] = (*a)[ii][jj] + b;
			}
		}
		return res;
	}

	template<>
	std::vector<double> sub<double>(std::vector<double>* a, double b)
	{
		std::vector<double> res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] - b;
		return res;
	}
	template<>
	std::vector< std::complex<double> > sub< std::complex<double> >(std::vector< std::complex<double> >* a, double b)
	{
		std::vector<  std::complex<double> > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] - b;
		return res;
	}

	template<>
	std::vector< std::vector<double> > sub< std::vector<double> >(std::vector< std::vector<double> >* a, double b)
	{
		std::vector<   std::vector<double>  > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
		{
			res[ii].resize( (*a)[ii].size() );
			for( int jj=0; jj < res[ii].size(); jj++)
			{
				res[ii][jj] = (*a)[ii][jj] - b;
			}
		}
		return res;
	}

	template<>
	std::vector<double> mul<double>(std::vector<double>* a, double b)
	{
		std::vector<double> res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] * b;
		return res;
	}
	template<>
	std::vector< std::complex<double> > mul< std::complex<double> >(std::vector< std::complex<double> >* a, double b)
	{
		std::vector<  std::complex<double> > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] * b;
		return res;
	}

	template<>
	std::vector< std::vector<double> > mul< std::vector<double> >(std::vector< std::vector<double> >* a, double b)
	{
		std::vector<   std::vector<double>  > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
		{
			res[ii].resize( (*a)[ii].size() );
			for( int jj=0; jj < res[ii].size(); jj++)
			{
				res[ii][jj] = (*a)[ii][jj] * b;
			}
		}
		return res;
	}

	template<>
	std::vector<double> div<double>(std::vector<double>* a, double b)
	{
		std::vector<double> res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] / b;
		return res;
	}
	template<>
	std::vector< std::complex<double> > div< std::complex<double> >(std::vector< std::complex<double> >* a, double b)
	{
		std::vector<  std::complex<double> > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
			res[ii] = (*a)[ii] / b;
		return res;
	}

	template<>
	std::vector< std::vector<double> > div< std::vector<double> >(std::vector< std::vector<double> >* a, double b)
	{
		std::vector<   std::vector<double>  > res(a->size());
		for( int ii=0; ii < res.size(); ii++)
		{
			res[ii].resize( (*a)[ii].size() );
			for( int jj=0; jj < res[ii].size(); jj++)
			{
				res[ii][jj] = (*a)[ii][jj] / b;
			}
		}
		return res;
	}
}

int tolua_luaVector_std_min_and_index00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     (tolua_isvaluenil(tolua_S,1,&tolua_err) || !tolua_isusertype(tolua_S,1,"const std::vector<double>",0,&tolua_err)) ||
     !tolua_isnoobj(tolua_S,4,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  const std::vector<double>* tolua_var_49 = ((const std::vector<double>*)  tolua_tousertype(tolua_S,1,0));
  double tolua_var_50 = ((double)  tolua_tonumber(tolua_S,2,0));
  int tolua_var_51 = ((int)  tolua_tonumber(tolua_S,3,0));
  {
   std::min_and_index(*tolua_var_49,tolua_var_50,tolua_var_51);
   tolua_pushnumber(tolua_S,(lua_Number)tolua_var_50);
   tolua_pushnumber(tolua_S,(lua_Number)tolua_var_51);
  }
 }
 return 2;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'min_and_index'.",&tolua_err);
 return 0;
#endif
}

/* function: std::min_and_index_with_range */
int tolua_luaVector_std_min_and_index_with_range00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     (tolua_isvaluenil(tolua_S,1,&tolua_err) || !tolua_isusertype(tolua_S,1,"const std::vector<double>",0,&tolua_err)) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,4,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  const std::vector<double>* vec = ((const std::vector<double>*)  tolua_tousertype(tolua_S,1,0));
  int min = ((int)  tolua_tonumber(tolua_S,2,0));
  int max = ((int)  tolua_tonumber(tolua_S,3,0));
  double val;
  int idx;
  {
   std::min_and_index_with_range(*vec,min,max,val,idx);
   tolua_pushnumber(tolua_S,(lua_Number)val);
   tolua_pushnumber(tolua_S,(lua_Number)idx);
  }
 }
 return 2;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'min_and_index_with_range'.",&tolua_err);
 return 0;
#endif
}



/* function: std::max_and_index */
int tolua_luaVector_std_max_and_index00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     (tolua_isvaluenil(tolua_S,1,&tolua_err) || !tolua_isusertype(tolua_S,1,"const std::vector<double>",0,&tolua_err)) ||
     !tolua_isnoobj(tolua_S,2,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  const std::vector<double>* vec = ((const std::vector<double>*)  tolua_tousertype(tolua_S,1,0));
  double val;
  int idx;
  {
   std::max_and_index(*vec,val,idx);
   tolua_pushnumber(tolua_S,(lua_Number)val);
   tolua_pushnumber(tolua_S,(lua_Number)idx);
  }
 }
 return 2;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'max_and_index'.",&tolua_err);
 return 0;
#endif
}

/* function: std::max_and_index_with_range */
int tolua_luaVector_std_max_and_index_with_range00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     (tolua_isvaluenil(tolua_S,1,&tolua_err) || !tolua_isusertype(tolua_S,1,"const std::vector<double>",0,&tolua_err)) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,4,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  const std::vector<double>* vec = ((const std::vector<double>*)  tolua_tousertype(tolua_S,1,0));
  int min = ((int)  tolua_tonumber(tolua_S,2,0));
  int max = ((int)  tolua_tonumber(tolua_S,3,0));
  double val;
  int idx;
  {
   std::max_and_index_with_range(*vec,min,max,val,idx);
   tolua_pushnumber(tolua_S,(lua_Number)val);
   tolua_pushnumber(tolua_S,(lua_Number)idx);
  }
 }
 return 2;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'max_and_index_with_range'.",&tolua_err);
 return 0;
#endif
}


/* method: vector_geti of class  std::vector<double> */
int tolua_luaVector_std_vector__geti00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"std::vector<double>",0,&tolua_err) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,3,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  std::vector<double>* self = (std::vector<double>*)  tolua_tousertype(tolua_S,1,0);
  int idx = ((int)  tolua_tonumber(tolua_S,2,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'vector_geti'", NULL);
#endif
  {
   tolua_outside double tolua_ret = (tolua_outside double)  vector_geti(self,idx);
   tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function '.geti'.",&tolua_err);
 return 0;
#endif
}

/* method: vector_seti of class  std::vector<double> */
int tolua_luaVector_std_vector__seti00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"std::vector<double>",0,&tolua_err) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,4,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  std::vector<double>* self = (std::vector<double>*)  tolua_tousertype(tolua_S,1,0);
  int idx = ((int)  tolua_tonumber(tolua_S,2,0));
  const double value = ((const double)  tolua_tonumber(tolua_S,3,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'vector_seti'", NULL);
#endif
  {
	  if (idx<0 || idx >= self->size() )
		  tolua_error(tolua_S,"out of range", NULL);

   vector_seti(self,idx,value);
   tolua_pushnumber(tolua_S,(lua_Number)value);
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function '.seti'.",&tolua_err);
 return 0;
#endif
}


/* method: vector_geti of class  std::vector<std::complex<double> > */
int tolua_luaVector_std_vector_std__complex_double_____geti00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"std::vector<std::complex<double> >",0,&tolua_err) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,3,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  std::vector<std::complex<double> >* self = (std::vector<std::complex<double> >*)  tolua_tousertype(tolua_S,1,0);
  int idx = ((int)  tolua_tonumber(tolua_S,2,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'vector_geti'", NULL);
#endif
  {
	  if (idx<0 || idx >= self->size() )
		  tolua_error(tolua_S,"out of range", NULL);

   tolua_outside std::complex<double> tolua_ret = (tolua_outside std::complex<double>)  vector_geti(self,idx);
   {
#ifdef __cplusplus
    void* tolua_obj = Mtolua_new((std::complex<double>)(tolua_ret));
     tolua_pushusertype(tolua_S,tolua_obj,"std::complex<double>");
    tolua_register_gc(tolua_S,lua_gettop(tolua_S));
#else
    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(std::complex<double>));
     tolua_pushusertype(tolua_S,tolua_obj,"std::complex<double>");
    tolua_register_gc(tolua_S,lua_gettop(tolua_S));
#endif
   }
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function '.geti'.",&tolua_err);
 return 0;
#endif
}

/* method: vector_seti of class  std::vector<std::complex<double> > */
int tolua_luaVector_std_vector_std__complex_double_____seti00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"std::vector<std::complex<double> >",0,&tolua_err) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const std::complex<double>",0,&tolua_err)) ||
     !tolua_isnoobj(tolua_S,4,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  std::vector<std::complex<double> >* self = (std::vector<std::complex<double> >*)  tolua_tousertype(tolua_S,1,0);
  int idx = ((int)  tolua_tonumber(tolua_S,2,0));
  const std::complex<double>* value = ((const std::complex<double>*)  tolua_tousertype(tolua_S,3,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'vector_seti'", NULL);
#endif
  {
	  if (idx<0 || idx >= self->size() )
		  tolua_error(tolua_S,"out of range", NULL);

   vector_seti(self,idx,*value);
  }
 }
 return 0;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function '.seti'.",&tolua_err);
 return 0;
#endif
}

/* method: vector_geti of class  std::vector<std::vector<double> > */
int tolua_luaVector_std_vector_std__vector____geti00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"std::vector<std::vector<double> >",0,&tolua_err) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,3,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  std::vector<std::vector<double> >* self = (std::vector<std::vector<double> >*)  tolua_tousertype(tolua_S,1,0);
  int idx = ((int)  tolua_tonumber(tolua_S,2,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'vector_geti'", NULL);
#endif
  {
	  if (idx<0 || idx >= self->size() )
		  tolua_error(tolua_S,"out of range", NULL);

   tolua_outside std::vector<double> tolua_ret = (tolua_outside std::vector<double>)  vector_geti(self,idx);
   {
#ifdef __cplusplus
    void* tolua_obj = Mtolua_new((std::vector<double>)(tolua_ret));
     tolua_pushusertype(tolua_S,tolua_obj,"std::vector<double>");
    tolua_register_gc(tolua_S,lua_gettop(tolua_S));
#else
    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(std::vector<double>));
     tolua_pushusertype(tolua_S,tolua_obj,"std::vector<double>");
    tolua_register_gc(tolua_S,lua_gettop(tolua_S));
#endif
   }
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function '.geti'.",&tolua_err);
 return 0;
#endif
}

/* method: vector_seti of class  std::vector<std::vector<double> > */
int tolua_luaVector_std_vector_std__vector____seti00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"std::vector<std::vector<double> >",0,&tolua_err) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const std::vector<double>",0,&tolua_err)) ||
     !tolua_isnoobj(tolua_S,4,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  std::vector<std::vector<double> >* self = (std::vector<std::vector<double> >*)  tolua_tousertype(tolua_S,1,0);
  int idx = ((int)  tolua_tonumber(tolua_S,2,0));
  const std::vector<double>* value = ((const std::vector<double>*)  tolua_tousertype(tolua_S,3,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'vector_seti'", NULL);
#endif
  {
	  if (idx<0 || idx >= self->size() )
		  tolua_error(tolua_S,"out of range", NULL);

   vector_seti(self,idx,*value);
  }
 }
 return 0;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function '.seti'.",&tolua_err);
 return 0;
#endif
}
